/*************************************************
 * 
 * Copyright by Bruno Eberhard
 * 
 * Created on 24.12.2005
 *
 *************************************************/
package fightplan.views.tables;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.table.TableCellEditor;

import com.jgoodies.binding.value.ValueModel;

import fightplan.business.AbstractFighter;
import fightplan.business.Category;
import fightplan.business.Tournament;

@SuppressWarnings("serial")
public class CategoryCellEditor extends AbstractCellEditor implements TableCellEditor {
	private ValueModel tournament;
	private AbstractFighter fighter;
	private JPopupMenu popupMenu;
	private JLabel label;

	public CategoryCellEditor(ValueModel tournament) {
		this.tournament = tournament;
	}

	public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
		fighter = (AbstractFighter) value;
		return create((Tournament) tournament.getValue(), (AbstractFighter) value);
	}

	public Object getCellEditorValue() {
		return fighter;
	}

	@Override
	public boolean stopCellEditing() {
		popupMenu.setVisible(false);
		return super.stopCellEditing();
	}

	@Override
	public void cancelCellEditing() {
		popupMenu.setVisible(false);
		super.cancelCellEditing();
	}

	private Component create(Tournament tournament, AbstractFighter fighter) {
		label = new PopupLabel(fighter.getCategoryNames(tournament));
		popupMenu = new JPopupMenu();
		popupMenu.setLayout(new BorderLayout());
		popupMenu.setFocusable(false);
		popupMenu.setLightWeightPopupEnabled(true);
		popupMenu.setBackground(Color.WHITE);
		popupMenu.setOpaque(true);
		popupMenu.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		JPanel panel = new JPanel(new GridLayout(0, 1));
		panel.setOpaque(false);

		boolean categoryFound = false;
		List<Category> categories = fighter.searchCategories(tournament);
		for (Category category : tournament.getCategories()) {
			if (category.compatible(fighter) || category.getFighters().contains(fighter)) {
				categoryFound = true;
				JCheckBox checkBox = createCheckBox(category.getNameOrDescription());
				checkBox.setSelected(categories.contains(category));
				checkBox.addActionListener(new CategoryCheckBoxListener(label, fighter, category));

				panel.add(checkBox);
			}
		}
		if (!categoryFound) {
			JLabel label2 = new JLabel("Keine mögliche Kategorie");
			label2.setBorder(BorderFactory.createEmptyBorder(4, 5, 4, 5));
			panel.add(label2);
		}

		JButton closeButton = new JButton("Schliessen");
		closeButton.setOpaque(false);
		closeButton.setFont(closeButton.getFont().deriveFont(Font.BOLD));
		closeButton.setBorder(null);
		closeButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				CategoryCellEditor.this.fireEditingStopped();
			}
		});
		panel.add(closeButton);
		popupMenu.add(panel, BorderLayout.CENTER);
		label.addAncestorListener(new AncestorListener() {
			public void ancestorAdded(AncestorEvent event) {
			}

			public void ancestorRemoved(AncestorEvent event) {
				popupMenu.setVisible(false);
			}

			public void ancestorMoved(AncestorEvent event) {
			}
		});
		return label;
	}

	private JCheckBox createCheckBox(String text) {
		JCheckBox checkBox = new JCheckBox(text);
		checkBox.setFocusable(false);
		checkBox.setOpaque(false);
		return checkBox;
	}

	private class PopupLabel extends JLabel {

		public PopupLabel(String text) {
			super(text);
		}

		@Override
		public void paint(Graphics g) {
			super.paint(g);
			popupMenu.setLocation(label.getLocationOnScreen().x, label.getLocationOnScreen().y + label.getHeight());
			popupMenu.setVisible(true);
		}
	}

	private class CategoryCheckBoxListener implements ActionListener {
		private JLabel label;
		private AbstractFighter fighter;
		private Category category;

		public CategoryCheckBoxListener(JLabel label, AbstractFighter fighter, Category category) {
			this.label = label;
			this.fighter = fighter;
			this.category = category;
		}

		public void actionPerformed(ActionEvent e) {
			JCheckBox checkBox = (JCheckBox) e.getSource();
			if (checkBox.isSelected()) {
				if (!category.getFighters().contains(fighter)) {
					category.getFighters().add(fighter);
					label.setText(fighter.getCategoryNames((Tournament) tournament.getValue()));
				}
			} else {
				if (category.getFighters().contains(fighter)) {
					category.getFighters().remove(fighter);
					label.setText(fighter.getCategoryNames((Tournament) tournament.getValue()));
				}
			}
		}
	}

}
